package pers.chao.tool.infrastructure.log;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.LevelFilter;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;

/**
 * Description: logback logger打印工具，仅控制台
 *
 * @author W.Chao
 * @date 2020/11/22 0:34
 **/
public final class BaseLogFactory {
	private static final String CONSOLE_APPENDER_NAME = "BASE-UTILS-CONSOLE";
	private static final String LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%thread] %cyan(%logger{50}): %msg%n";

	/**
	 * 控制台日志打印，默认debug
	 *
	 * @param clazz
	 * @return
	 */
	public static Logger getLogger(Class clazz) {
		return getLogger(clazz, Level.INFO);
	}

	/**
	 * 控制台日志打印
	 *
	 * @param clazz
	 * @param level
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Logger getLogger(Class clazz, Level level) {
		ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(clazz);
		LoggerContext loggerContext = logger.getLoggerContext();
		ConsoleAppender realConsoleAppenderCommon = createConsoleAppender(loggerContext, level);
		logger.setAdditive(false);
		logger.addAppender(realConsoleAppenderCommon);
		return logger;
	}

	/**
	 * 创建控制台appender
	 *
	 * @param loggerContext
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static ConsoleAppender createConsoleAppender(LoggerContext loggerContext, Level level) {
		ConsoleAppender appender = new ConsoleAppender();
		appender.setContext(loggerContext);
		appender.setName(CONSOLE_APPENDER_NAME);
		appender.addFilter(createLevelFilter(level));
		appender.setEncoder(createEncoder(loggerContext, LOG_PATTERN));
		appender.start();
		return appender;
	}

	/**
	 * 设置日志输出格式
	 *
	 * @param context
	 * @param logPattern
	 * @return
	 */
	private static PatternLayoutEncoder createEncoder(LoggerContext context, String logPattern) {
		PatternLayoutEncoder encoder = new PatternLayoutEncoder();
		// 设置上下文，每个logger都关联到logger上下文，默认上下文名称为default。
		// 但可以使用<scope="context">设置成其他名字，用于区分不同应用程序的记录。一旦设置，不能修改。
		encoder.setContext(context);
		// 设置格式
		encoder.setPattern(logPattern);
		encoder.setCharset(StandardCharsets.UTF_8);
		encoder.start();
		return encoder;
	}

	/**
	 * 设置打印日志的级别
	 *
	 * @param level
	 * @return
	 */
	private static Filter createLevelFilter(Level level) {
		LevelFilter levelFilter = new LevelFilter();
		levelFilter.setLevel(level);
		levelFilter.setOnMatch(FilterReply.ACCEPT);
		levelFilter.setOnMismatch(FilterReply.DENY);
		levelFilter.start();
		return levelFilter;
	}
}
